﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing;

namespace LedCenter.GUI
{
    /// <summary>
    /// DoubleBufferedTableLayoutPanel class
    /// </summary>
    class DoubleBufferedTableLayoutPanel : TableLayoutPanel
    {
        private const int TABLE_CELL_WIDTH = 70; // Cell width
        private const int TABLE_CELL_HEIGHT = 40;// Cell height
        private const int TABLE_CELL_PADDING = 5;// Cell padding
        private Font TABLE_CELL_FONT = new Font("Tahoma",          // Font family
                                                14F,               // Font size
                                                FontStyle.Regular, // Font style
                                                GraphicsUnit.Point,// Font unit 
                                                ((byte)(0)));      // Encoding

        /// <summary>
        /// Default constructor
        /// </summary>
        /// <returns></returns>
        public DoubleBufferedTableLayoutPanel()
        {
            DoubleBuffered = true;

        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (this.Parent != null)
            {
                if (Height >= this.Parent.Height - 50)
                    Height = this.Parent.Height - 50;
            }
            //else
                //this.Height = 100;
        }
        private string[,] _data;

        /// <summary>
        /// Re init table with columns and row
        /// </summary>
        /// <param name="column">Number of columns</param>
        /// <param name="row">Number of rows</param>
        /// <returns></returns>
        public void ReInitTable(uint column, uint row)
        {
            // Clear old configs and data
            this.Controls.Clear(); // Controls
            this.RowStyles.Clear();// Row styles
            this.ColumnStyles.Clear();// Column styles
            this.ColumnCount = (int)column+1;// There is header column, so we add +1 to column count.
            this.RowCount = (int)row;// Row count

            // Add new row styles
            for (int i = 0; i < RowCount;i++)
            {
                RowStyles.Add(new RowStyle(SizeType.Absolute, TABLE_CELL_HEIGHT));
            }

            // Add new column styles
            for (int i = 0; i < ColumnCount; i++)
            {
                ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, TABLE_CELL_WIDTH));
            }

            int width = 0; // actual width
            int height = 0;// actual height
            
            // Add controls bases on array data
            for (int i = 0; i < RowCount; i++)
            {
                height += TABLE_CELL_HEIGHT;
                if (i == RowCount - 1)
                    height += 0;
                for (int j = 0; j < ColumnCount; j++)
                {
                    if (j == 0)
                    {
                        // Create first column for header
                        Label lbl = new Label();    // Init
                        lbl.AutoSize = false;       // disable auto resize
                        lbl.Dock = DockStyle.Fill;  // Fill control to fit parent cell
                        lbl.TextAlign = ContentAlignment.MiddleLeft; // Set text to the middle left of cell
                        lbl.Text = "Row: " + i.ToString();// set label's text
                        lbl.Size = new Size(
                                        TABLE_CELL_WIDTH, 
                                        TABLE_CELL_HEIGHT);// Size is fix (60,40)
                        // to count actual width of table, We only count for first row
                        if (i == 0)
                            width += lbl.Width;// calculate actual width

                        // Add label to list controls
                        Controls.Add(lbl, j, i);
                    }
                    else
                    {
                        // Create control data
                        NumericUpDown numTemp = new NumericUpDown();// Init
                        ((System.ComponentModel.ISupportInitialize)(numTemp)).BeginInit();
                        numTemp.Dock = DockStyle.Fill; // Fill control to fit parent cell
                        numTemp.Font = TABLE_CELL_FONT;// Font
                        numTemp.CausesValidation = true;//Enable number check
                        numTemp.Margin = new Padding(TABLE_CELL_PADDING);// Margins
                        numTemp.TextAlign = HorizontalAlignment.Center;  // Text align
                        numTemp.Size = new Size(                         // Size
                                            TABLE_CELL_WIDTH,   // size's width
                                            TABLE_CELL_HEIGHT); // size's height         
                        numTemp.Maximum = 1000;             // Maximum
                        numTemp.Minimum = 0;                // Minimum
                        numTemp.Value = 0;                  // Value
                        numTemp.Increment = (Decimal)0.1F;         // Increment
                        numTemp.ReadOnly = true;                         // Disable text prompt
                        
                        // to count actual width of table, We only count for first row
                        if (i == 0)
                        {
                            width += numTemp.Width;
                            if (j == ColumnCount - 1)
                                width += 0;
                        }
                        Controls.Add(numTemp, j, i);
                        ((System.ComponentModel.ISupportInitialize)(numTemp)).EndInit();
                    }
                    
                }
            }

            // Update new dimension
            this.Height = height + System.Windows.Forms.SystemInformation.HorizontalScrollBarHeight;
            this.Width = width + System.Windows.Forms.SystemInformation.VerticalScrollBarWidth;
        }

        // Increase
        public void AddRowControl(Type type)
        {

            int rowIndex = AddTableRow();

            //RowStyles.Add(new RowStyle(SizeType.Percent, 100F));

            if (RowCount > 1)
            {
                Label lbl = new Label();

                lbl.Text = "Row: " + rowIndex.ToString();
                Controls.Add(lbl, 0, rowIndex);

                for (int i = 1; i < ColumnCount; i++)
                {
                    if (type == typeof(NumericUpDown))
                    {
                        NumericUpDown numTemp = new NumericUpDown();
                        ((System.ComponentModel.ISupportInitialize)(numTemp)).BeginInit();
                        numTemp.Dock = System.Windows.Forms.DockStyle.Fill;
                        numTemp.Location = new System.Drawing.Point(3, 3);
                        numTemp.Font = new System.Drawing.Font("Tahoma", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                        numTemp.Margin = new System.Windows.Forms.Padding(7);
                        numTemp.Maximum = new decimal(new int[] {
                                                                10,
                                                                0,
                                                                0,
                                                                0});
                        Controls.Add(numTemp, i, rowIndex);
                    }

                }
            }
            this.Height = RowCount * 50;

        }
        public int AddTableRow()
        {
            int index = RowCount++;
            RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
            
            return index;
        }

        public void AddColumnControl(Type type)
        {

            int columnIndex = AddTableColumn();

            //ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));

            for (int i = 0; i < RowCount; i++)
            {
                if (type == typeof(NumericUpDown))
                {
                    NumericUpDown numTemp = new NumericUpDown();
                    numTemp.Location = new System.Drawing.Point(3, 3);
                    numTemp.Dock = System.Windows.Forms.DockStyle.Fill;
                    numTemp.Font = new System.Drawing.Font("Tahoma", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    numTemp.Maximum = new decimal(new int[] {
                    10,
                    0,
                    0,
                    0});
                    Controls.Add(numTemp, columnIndex, i);
                }

            }
            this.Width = ColumnCount * 50 + 0;
        }

        public int AddTableColumn()
        {
            int index = ColumnCount++;
            ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));

            return index;
        }

        public void DecreaseRow(int rowNumber)
        {
            if (rowNumber > this.RowCount || rowNumber <= 1) return;

            try
            {
                int lastRow = 0;
                lock (Controls)
                {


                    foreach (Control control in Controls)
                    {
                        int row = GetRow(control);
                        if (row >= rowNumber && row < RowCount)
                        {
                            Debug.WriteLine("Del row: " + row + "row count: " + RowCount);
                            Debug.WriteLine("   >>> Control: " + control.Name);
                            Controls.Remove(control);
                            if (lastRow > row)
                                RowStyles.RemoveAt(rowNumber);
                        }
                        lastRow = row;
                    }
                }
                RowCount = rowNumber;
                this.Height = RowCount * 50 + 0;
            }
            catch (System.Exception ex)
            {
                int a = 0;
            }
           
        }

        public void RemoveRow(int rowNumber)
        {
            foreach (Control control in Controls)
            {
                int row = GetRow(control);
                if (row == rowNumber)
                {
                    Controls.Remove(control);
                }
            }
            RowStyles.RemoveAt(rowNumber);

            foreach (Control control in Controls)
            {
                int row = GetRow(control);
                if (row > rowNumber)
                {
                    SetRow(control, row - 1);
                }
            }
        }

        public void DecreaseColumn(int columnNumber)
        {
            if (columnNumber > this.ColumnCount || columnNumber <= 1) return;

            int lastCol = 0;
            foreach (Control control in Controls)
            {
                int column = GetColumn(control);
                if (column >= columnNumber)
                {
                    Debug.WriteLine("Del col: " + column);
                    Controls.Remove(control);
                    if (lastCol > column)
                        ColumnStyles.RemoveAt(columnNumber);
                }
                lastCol = column;
            }
            ColumnCount = columnNumber;
            this.Width = ColumnCount * 50 + 0;
        }

        public void RemoveColumns(int columnNumber)
        {
            foreach (Control control in Controls)
            {
                int column = GetColumn(control);
                if (column == columnNumber)
                {
                    Controls.Remove(control);
                }
            }
            RowStyles.RemoveAt(columnNumber);

            foreach (Control control in Controls)
            {
                int column = GetColumn(control);
                if (column > columnNumber)
                {
                    SetRow(control, column - 1);
                }
            }
        }
    }
}
